package com.feiyuan.generator;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.Test;

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;

public class CodeGenerator {

    @Test
    public void genCode() {

        // 1、创建代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 2、全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
//        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setOutputDir(projectPath + "/test/src/main/java");
        gc.setAuthor("Xupf");
        gc.setOpen(false); //生成后是否打开资源管理器
        gc.setServiceName("%sService");	//去掉Service接口的首字母I
        gc.setIdType(IdType.AUTO); //主键策略
        gc.setSwagger2(true);//开启Swagger2模式
        mpg.setGlobalConfig(gc);

        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/srb_core?serverTimezone=GMT%2B8&characterEncoding=utf-8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 4、包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.feiyuan");
        pc.setEntity("pojo.entity"); //此对象与数据库表结构一一对应，通过 DAO 层向上传输数据源对象。
        pc.setModuleName("core");
        mpg.setPackageInfo(pc);

        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略

        strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
        strategy.setEntityLombokModel(true); // lombok
        strategy.setLogicDeleteFieldName("is_deleted");//逻辑删除字段名
        strategy.setEntityBooleanColumnRemoveIsPrefix(true);//去掉布尔值的is_前缀（确保tinyint(1)）
        strategy.setRestControllerStyle(true); //restful api风格控制器

        TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
        TableFill updateTime = new TableFill("update_time", FieldFill.INSERT_UPDATE);
        List<TableFill> fillList = new ArrayList<>();
        fillList.add(createTime);
        fillList.add(updateTime);
        strategy.setTableFillList(fillList);

//        strategy.setInclude(scanner("表名，多个英文逗号分割").split(","));
        // TODO 下次记得改这里
        strategy.setInclude(new String[]{"admin_menu", "admin_user"});
        mpg.setStrategy(strategy);

        InjectionConfig injectionConfig = new InjectionConfig() {
            //自定义属性注入:abc
            //在.ftl(或者是.vm)模板中，通过${cfg.abc}获取属性
            @Override
            public void initMap() {
//                Map<String, Object> map = new HashMap<>();
//                map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
//                this.setMap(map);
            }
        };
        String vueOutFilePath = projectPath + "/test/src/main/resources" + "/";
        List<FileOutConfig> files = new ArrayList<FileOutConfig>();
        files.add(new FileOutConfig("templates/demo.vue.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                String outFile = vueOutFilePath + tableInfo.getEntityName() + ".vue";
                return outFile;
            }
        });
        files.add(new FileOutConfig("templates/demo-save-or-update.vue.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                String outFile = vueOutFilePath + tableInfo.getEntityName() + "-save-or-update.vue";
                return outFile;
            }
        });
        files.add(new FileOutConfig("templates/demo.js.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                String outFile = vueOutFilePath + tableInfo.getEntityName() + ".js";
                return outFile;
            }
        });
        injectionConfig.setFileOutConfigList(files);
        mpg.setCfg(injectionConfig);


        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setController("templates/controller.java");
        templateConfig.setService("templates/Service.java");
        templateConfig.setServiceImpl("templates/ServiceImpl.java");
        mpg.setTemplate(templateConfig);
//        mpg.setTemplateEngine(new MyTemplateEngine());

        // 6、执行
        mpg.execute();

        // 7.文件生成以后执行打包操作


        // 8.删除生成的文件只保留打包后的文件
//        try {
//            this.deleteFiles();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

    }

    private void deleteFiles() throws IOException {
        Path path = Paths.get("E:\\my_project\\srb-project\\srb-project\\srb\\srb-generator/test");

        Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                Files.delete(file);
                System.out.println("文件被删除:" + file);
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                System.out.println("文件夹被删除：" + dir);
                return FileVisitResult.CONTINUE;
            }
        });
    }

    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
//    public static String scanner(String tip) {
//        Scanner scanner = new Scanner(System.in);
//        StringBuilder help = new StringBuilder();
//        help.append("请输入" + tip + "：");
//        System.out.println(help.toString());
//        if (scanner.hasNext()) {
//            String ipt = scanner.next();
//            if (StringUtils.isNotBlank(ipt)) {
//                return ipt;
//            }
//        }
//        throw new MybatisPlusException("请输入正确的" + tip + "！");
//    }
}
